Jx.declare('Jx.lib.Operation', {

	$accessors: {

		'successful': false,

		'completed': false,

		'error': undefined

	},

	$$precallback: function(properties, SuperClass){

		var SuperCodes = SuperClass.prototype.errorCodes,

			MyCodes = properties.errorCodes,

			J = Jx;

		if (!J.isObject(MyCodes)){

			MyCodes = properties.errorCodes = {};

		}

		if (J.isObject(SuperCodes)){

			J.assignIf(MyCodes, SuperCodes, true);

		}

	},

	errors: undefined,

	errorCodes: {

		1: 'Unknown'

	},

	defaultErrorCode: 1,

	timeCompleted: 0,

	onConstruct: function(){

		this.errors = [];

		this.$super(arguments);

	},

	allowSetSuccessful: function(o, success){

		o.value = success !== false;

	},

	allowSetCompleted: function(o, completed){

		o.value = completed !== false;

		o.execAfter = true;

	},

	onAfterSetCompleted: function(o){

		this.timeCompleted = Math.floor((new Date()).getTime() / 1000);

	},

	allowSetError: function(o, code, message){

		if (arguments.length == 2){

			message = code;

			code = this.defaultErrorCode;

		}

		var J = Jx,

			codes = this.errorCodes,

			valid = o.valid = J.isScalar(codes) && code in codes;

		if (valid){

			o.errorCode = code;

			o.errorLabel = codes[code];

			o.message = J.isScalar(message) ? String(message) : '...';

		}

	},

	onSetError: function(o){

		var errors = this.errors,

			i = errors.length;

		errors[i] = o.data.error = {

			code: o.errorCode,

			label: o.errorLabel,

			message: o.message

		};

	},

	formatGetError: function(o){

		var obj = o.data.error;

		o.returnValue = '';

		if (obj){

			o.returnValue = 'Error '+obj.code+' ['+obj.label+'] '+o.message;

		}

	}



});
